﻿Public Class Command
    Inherits ObservableImpl
    Implements Observer
    Implements NamedStatusObservable
    Implements Resetable
    Private name As String
    Private status As CommandStatus = CommandStatus.Idle
    Private receiver As Receiver
    Private dependencyList As List(Of Command) = New List(Of Command)

    Sub New(ByVal aName As String, ByRef aReceiver As Receiver)
        name = aName
        receiver = aReceiver
    End Sub

    Function getName() As String Implements NamedStatusObservable.getName
        Return name
    End Function

    Public Sub addDependency(ByRef dependency As Command)
        dependencyList.Add(dependency)
    End Sub

    Function getStatusDescription() As String Implements NamedStatusObservable.getStatusDescription
        Select Case status
            Case CommandStatus.Idle
                Return "Idle"
            Case CommandStatus.Processing
                Return "Processing "
            Case CommandStatus.Done
                Return "Done"
        End Select
        Return ""
    End Function

    Public Sub execute()
        receiver.Register(Me)
        receiver.executeCommand(Me)
    End Sub

    Sub Notify() Implements Observer.Notify
        If receiver.isProcessing() Then
            status = CommandStatus.Processing
        ElseIf receiver.isDone() Then
            status = CommandStatus.Done
            receiver.UnRegister(Me)
        End If
        NotifyObservers()
    End Sub

    Public Function canBeExecuted() As Boolean
        Return status = CommandStatus.Idle AndAlso receiver.isAvailable() AndAlso allDepencenciesFinalized()
    End Function

    Private Function allDepencenciesFinalized() As Boolean
        For Each depencency In dependencyList
            If Not depencency.hasFinalized() Then
                Return False
            End If
        Next
        Return True
    End Function

    Public Function executionFinalized() As Boolean
        Return status = CommandStatus.Done
    End Function

    Public Function getTotalEstimation() As Integer
        Return receiver.getTotalEstimation()
    End Function

    Public Function isIdle() As Boolean
        Return status = CommandStatus.Idle
    End Function

    Public Function hasFinalized() As Boolean
        Return status = CommandStatus.Done
    End Function

    Sub reset() Implements Resetable.reset
        status = CommandStatus.Idle
        NotifyObservers()
        receiver.reset()
    End Sub
End Class
